package com.example.design.filter.context;

import com.example.design.DateUtils;
import com.example.design.filter.enums.ScheduleShiftEnum;
import com.example.design.filter.enums.ScheduleTagEnum;
import com.example.design.filter.enums.ScheduleTypeEnum;
import com.example.design.filter.model.ActScheduleUserDO;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;

import java.time.LocalDate;
import java.util.*;

/**
 * 客服的排班记录
 */
@Getter
@Setter
@Accessors(chain = true)
public class ScheduleUser {

    private Long userId;

    private String realName;

    /**
     * 排班小组id
     */
    private Long teamId;

    /**
     * 排班小组下的店铺
     */
    private List<Long> shopIds;

    /**
     * 排班标签
     */
    private List<ScheduleTag> tags;

    /**
     * 排班类型 区分 售前or售后
     */
    private ScheduleTypeEnum scheduleType;

    /**
     * 上周日的排班班次
     */
    private ScheduleShiftEnum lastSundayShift;

    /**
     * 本周客服排班班次 map结构: <Date(yyyyMMdd), ScheduleShiftEnum.class>
     */
    private Map<String, ScheduleShiftEnum> shiftMap = new HashMap<>(64);

    public ScheduleUser(ActScheduleUserDO user, List<ScheduleTag> tags) {
        this.userId = user.getUserId();
        this.realName = user.getRealName();
        this.teamId = user.getTeamId();
        this.tags = tags == null ? new ArrayList<>() : tags;
    }

    /**
     * 今天不上班
     */
    public boolean noWorkToday(ScheduleTagEnum noWorkTag, Date date) {
        Optional<ScheduleTag> noWork = tags.stream()
                .filter(tag -> tag.valid(noWorkTag, date))
                .findFirst();
        return noWork.isPresent();
    }

    /**
     * 今天请假
     */
    public boolean leaveToday(Date date) {
        Optional<ScheduleTag> vacation = tags.stream()
                .filter(tag -> tag.valid(ScheduleTagEnum.LEAVE, date))
                .findFirst();
        return vacation.isPresent();
    }

    /**
     * 本周已经上班的天数
     */
    public long workDays(LocalDate date) {
        int workDays = 0;
        int dayOfWeek = date.getDayOfWeek().getValue();
        LocalDate weekStart = date.plusDays(-1 * dayOfWeek + 1);
        for (int i = 0; i < dayOfWeek - 1; i++) {
            String dateKey = weekStart.plusDays(i).format(DateUtils.FORMAT_YYYYMMDD);
            if (shiftMap.get(dateKey) != null && !shiftMap.get(dateKey).equals(scheduleType.getRestShift())) {
                workDays++;
            }
        }
        return workDays;
    }

    /**
     * 本周休息的天数（不包括今天）（向后考虑不上班的标签）
     */
    public long restDays(LocalDate date) {
        int dayOfWeek = date.getDayOfWeek().getValue();
        int restDays = 0;
        for (int i = 1; i < dayOfWeek; i++) {
            String dateKey = date.plusDays(-1 * i).format(DateUtils.FORMAT_YYYYMMDD);
            if (scheduleType.getRestShift().equals(shiftMap.get(dateKey))) {
                restDays++;
            }
        }
        if (dayOfWeek >= 7) {
            return restDays;
        }
        // 向后考虑不上班的情况（不包括今天）
        int leftDays = 7 - dayOfWeek;
        for (int i = 1; i <= leftDays; i++) {
            LocalDate localDate = date.plusDays(i);
            ScheduleTagEnum noWorkTag = ScheduleTagEnum.getByDayOfWeek(
                    localDate.getDayOfWeek().getValue()
            );
            if (this.noWorkToday(noWorkTag, DateUtils.localDate2Date(localDate))) {
                restDays++;
            }
        }
        return restDays;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        ScheduleUser that = (ScheduleUser) o;
        return userId.equals(that.userId);
    }

    @Override
    public int hashCode() {
        return Objects.hash(userId);
    }
}
